#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
稳定版福特配置器分析器
优化加载时间和错误处理，确保分析过程的稳定性
"""

import json
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException, NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service


class StableConfiguratorAnalyzer:
    """稳定版配置器分析器"""
    
    def __init__(self):
        self.driver = None
        self.wait = None
        self.analysis_results = {}
        self.html_snapshots = {}
        self.detected_models = []
        self.setup_driver()
    
    def setup_driver(self):
        """初始化Chrome WebDriver - 稳定版配置"""
        try:
            print("正在初始化Chrome WebDriver（稳定版配置）...")
            
            options = Options()
            options.add_argument('--no-sandbox')
            options.add_argument('--disable-dev-shm-usage')
            options.add_argument('--disable-gpu')
            options.add_argument('--window-size=1920,1080')
            
            # 稳定性优化
            options.add_argument('--disable-extensions')
            options.add_argument('--disable-plugins')
            options.add_argument('--disable-background-timer-throttling')
            options.add_argument('--disable-backgrounding-occluded-windows')
            options.add_argument('--disable-renderer-backgrounding')
            options.add_argument('--disable-features=TranslateUI')
            options.add_argument('--disable-ipc-flooding-protection')
            
            # 内存优化
            options.add_argument('--memory-pressure-off')
            options.add_argument('--max_old_space_size=4096')
            
            # 网络优化
            options.add_argument('--aggressive-cache-discard')
            options.add_argument('--disable-background-networking')
            
            # 设置User-Agent
            options.add_argument('--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
            
            try:
                from webdriver_manager.chrome import ChromeDriverManager
                service = Service(ChromeDriverManager().install())
                self.driver = webdriver.Chrome(service=service, options=options)
            except Exception:
                self.driver = webdriver.Chrome(options=options)
            
            self.wait = WebDriverWait(self.driver, 20)
            
            # 清除cookies
            self.driver.delete_all_cookies()
            
            print("WebDriver初始化成功")
            
        except Exception as e:
            print(f"WebDriver初始化失败: {e}")
            raise
    
    def check_browser_health(self):
        """检查浏览器健康状态"""
        try:
            # 尝试获取当前URL来验证浏览器是否还活着
            current_url = self.driver.current_url
            return True
        except Exception as e:
            print(f"⚠️  浏览器健康检查失败: {e}")
            return False
    
    def enhanced_cookie_handler_stable(self):
        """稳定版增强Cookie处理"""
        print("🍪 执行稳定版Cookie处理...")
        
        if not self.check_browser_health():
            print("❌ 浏览器不可用，跳过Cookie处理")
            return False
        
        try:
            # 等待页面稳定
            time.sleep(3)
            
            # 方法1: 直接JavaScript移除所有可能的Cookie弹窗
            print("  🔧 使用JavaScript强制清理Cookie弹窗...")
            removed_count = self.force_remove_cookie_elements()
            
            # 方法2: 查找并点击同意按钮
            print("  🔍 查找Cookie同意按钮...")
            button_clicked = self.find_and_click_accept_button()
            
            # 方法3: 最终验证和清理
            print("  ✅ 验证页面交互性...")
            interactive = self.verify_page_interactive()
            
            success = removed_count > 0 or button_clicked or interactive
            
            if success:
                print("✅ Cookie处理完成")
            else:
                print("⚠️  Cookie处理效果未知，继续执行")
            
            return True
            
        except Exception as e:
            print(f"❌ Cookie处理出错: {e}")
            return False
    
    def force_remove_cookie_elements(self):
        """使用JavaScript强制移除Cookie元素"""
        try:
            cleanup_script = """
            var removedCount = 0;
            
            // 福特特定的Cookie选择器
            var fordSelectors = [
                '.styles__CookieDisclaimerWrapper-sc-dx4a8y-0',
                '.styles__CookieDisclaimerContent-sc-dx4a8y-3',
                '[class*="styles__CookieDisclaimer"]',
                '[class*="CookieDisclaimer"]'
            ];
            
            // 通用Cookie选择器
            var genericSelectors = [
                '[class*="cookie"]',
                '[class*="Cookie"]',
                '[class*="consent"]',
                '[id*="cookie"]',
                '[role="dialog"]',
                '[class*="modal"]',
                '[class*="overlay"]',
                '[class*="backdrop"]'
            ];
            
            // 处理福特特定选择器
            fordSelectors.forEach(function(selector) {
                try {
                    var elements = document.querySelectorAll(selector);
                    elements.forEach(function(el) {
                        if (el && el.offsetParent !== null) {
                            el.style.display = 'none';
                            el.remove();
                            removedCount++;
                        }
                    });
                } catch(e) {}
            });
            
            // 处理通用选择器（更保守）
            genericSelectors.forEach(function(selector) {
                try {
                    var elements = document.querySelectorAll(selector);
                    elements.forEach(function(el) {
                        if (el && el.offsetParent !== null) {
                            var rect = el.getBoundingClientRect();
                            // 只移除大的overlay元素
                            if (rect.width > 200 && rect.height > 100) {
                                var zIndex = window.getComputedStyle(el).zIndex;
                                if (zIndex && parseInt(zIndex) > 100) {
                                    el.style.display = 'none';
                                    el.remove();
                                    removedCount++;
                                }
                            }
                        }
                    });
                } catch(e) {}
            });
            
            // 重置页面样式
            document.body.style.overflow = 'auto';
            document.documentElement.style.overflow = 'auto';
            
            return removedCount;
            """
            
            removed_count = self.driver.execute_script(cleanup_script)
            if removed_count > 0:
                print(f"    🗑️  移除了 {removed_count} 个Cookie相关元素")
            
            return removed_count
            
        except Exception as e:
            print(f"    ❌ JavaScript清理失败: {e}")
            return 0
    
    def find_and_click_accept_button(self):
        """查找并点击同意按钮"""
        try:
            # 同意按钮的可能选择器
            accept_selectors = [
                'button[data-testid*="accept"]',
                'button[id*="accept"]', 
                'button[class*="accept"]',
                'button[aria-label*="accept" i]',
                'button[aria-label*="Allow" i]',
                'button'
            ]
            
            for selector in accept_selectors:
                try:
                    buttons = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for button in buttons:
                        if self.is_likely_accept_button(button):
                            # 尝试点击
                            try:
                                self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", button)
                                time.sleep(0.5)
                                button.click()
                                print(f"    ✅ 成功点击按钮: '{button.text.strip()[:30]}'")
                                time.sleep(2)
                                return True
                            except Exception:
                                # 尝试JavaScript点击
                                try:
                                    self.driver.execute_script("arguments[0].click();", button)
                                    print(f"    ✅ JavaScript点击按钮: '{button.text.strip()[:30]}'")
                                    time.sleep(2)
                                    return True
                                except Exception:
                                    continue
                except Exception:
                    continue
            
            return False
            
        except Exception as e:
            print(f"    ❌ 查找按钮失败: {e}")
            return False
    
    def is_likely_accept_button(self, button):
        """判断是否可能是同意按钮"""
        try:
            if not button.is_displayed() or not button.is_enabled():
                return False
            
            text = button.text.strip().lower()
            if len(text) == 0:
                return False
            
            # 明确的同意词汇
            accept_words = ['accept', 'agree', 'allow', 'ok', 'continue', 'yes']
            reject_words = ['reject', 'decline', 'no', 'manage', 'settings', 'customize']
            
            has_accept = any(word in text for word in accept_words)
            has_reject = any(word in text for word in reject_words)
            
            # 如果包含同意词汇且不包含拒绝词汇
            return has_accept and not has_reject
            
        except Exception:
            return False
    
    def verify_page_interactive(self):
        """验证页面是否可交互"""
        try:
            # 查找车型元素
            model_elements = self.driver.find_elements(By.CSS_SELECTOR, 'div[data-cy][class*="ProductTile"]')
            
            interactive_count = 0
            for model in model_elements:
                data_cy = model.get_attribute('data-cy')
                if data_cy and len(data_cy) > 2:
                    try:
                        # 检查元素位置
                        location = model.location
                        size = model.size
                        if location['y'] > 0 and size['width'] > 0:
                            interactive_count += 1
                    except Exception:
                        continue
            
            print(f"    ✓ 发现 {interactive_count} 个可交互车型元素")
            return interactive_count > 0
            
        except Exception as e:
            print(f"    ❌ 验证交互性失败: {e}")
            return False
    
    def analyze_with_progressive_loading(self, url):
        """渐进式加载分析"""
        try:
            print(f"🚀 开始渐进式分析: {url}")
            print("=" * 60)
            
            # 阶段1: 快速访问页面
            print("\\n📱 阶段1: 页面访问")
            self.driver.get(url)
            print("✅ 页面访问完成")
            
            # 阶段2: 逐步等待和检查
            print("\\n⏳ 阶段2: 渐进式加载检查")
            self.progressive_wait_and_check()
            
            # 阶段3: Cookie处理
            print("\\n🍪 阶段3: Cookie处理")
            if self.check_browser_health():
                self.enhanced_cookie_handler_stable()
            else:
                print("❌ 浏览器不可用，跳过Cookie处理")
                return
            
            # 阶段4: 数据提取
            print("\\n🔍 阶段4: 数据提取")
            if self.check_browser_health():
                self.extract_page_data()
            else:
                print("❌ 浏览器不可用，跳过数据提取")
                return
            
            # 阶段5: 测试交互
            print("\\n🎯 阶段5: 交互测试")
            if self.check_browser_health():
                self.test_interactions()
            else:
                print("❌ 浏览器不可用，跳过交互测试")
                return
            
            # 阶段6: 生成报告
            print("\\n📋 阶段6: 生成报告")
            self.generate_stable_report()
            
        except Exception as e:
            print(f"❌ 分析过程出错: {e}")
        finally:
            print("\\n🏁 分析完成")
            input("按 Enter 键关闭浏览器...")
            self.cleanup()
    
    def progressive_wait_and_check(self):
        """渐进式等待和检查"""
        max_wait = 15  # 减少到15秒
        check_interval = 3
        
        for i in range(0, max_wait, check_interval):
            print(f"  ⏱️  等待 {i+check_interval}/{max_wait} 秒...")
            time.sleep(check_interval)
            
            # 检查浏览器健康状态
            if not self.check_browser_health():
                print(f"  ❌ 浏览器在第 {i+check_interval} 秒时失去响应")
                return False
            
            # 检查页面是否有内容
            try:
                body_text = self.driver.find_element(By.TAG_NAME, "body").text
                if len(body_text) > 1000:
                    print(f"  ✅ 页面内容已加载 (第 {i+check_interval} 秒)")
                    break
            except Exception:
                continue
        
        print("✅ 渐进式加载完成")
        return True
    
    def extract_page_data(self):
        """提取页面数据"""
        try:
            # 获取页面基本信息
            page_info = {
                'url': self.driver.current_url,
                'title': self.driver.title,
                'html_length': len(self.driver.page_source)
            }
            
            print(f"  📄 页面信息:")
            print(f"     URL: {page_info['url']}")
            print(f"     标题: {page_info['title']}")
            print(f"     HTML长度: {page_info['html_length']:,} 字符")
            
            # 提取导航信息
            navigation = self.extract_navigation_info()
            print(f"  🧭 导航: {len(navigation)} 个步骤")
            
            # 提取车型信息
            models = self.extract_model_info()
            print(f"  🚗 车型: {len(models)} 个")
            
            # 保存数据
            self.analysis_results = {
                'page_info': page_info,
                'navigation': navigation,
                'models': models,
                'extraction_timestamp': time.time()
            }
            
            self.detected_models = models
            
        except Exception as e:
            print(f"  ❌ 数据提取失败: {e}")
    
    def extract_navigation_info(self):
        """提取导航信息"""
        try:
            nav_container = self.driver.find_element(By.CSS_SELECTOR, 'nav[data-testid="Navigation_Container"]')
            nav_items = nav_container.find_elements(By.CSS_SELECTOR, 'button, a')
            
            navigation = []
            for item in nav_items:
                if item.is_displayed():
                    text = item.text.strip()
                    if text and len(text) < 20:
                        navigation.append({
                            'text': text,
                            'enabled': item.is_enabled(),
                            'aria_disabled': item.get_attribute('aria-disabled'),
                            'class': item.get_attribute('class')
                        })
            
            return navigation
        except Exception:
            return []
    
    def extract_model_info(self):
        """提取车型信息"""
        try:
            model_elements = self.driver.find_elements(By.CSS_SELECTOR, 'div[data-cy][class*="ProductTile"]')
            
            models = []
            for model in model_elements:
                data_cy = model.get_attribute('data-cy')
                if data_cy and data_cy not in ['header-selling-price', 'sticky-bar']:
                    try:
                        text = model.text.strip()
                        models.append({
                            'name': data_cy,
                            'text_preview': text[:100] + "..." if len(text) > 100 else text,
                            'displayed': model.is_displayed()
                        })
                    except Exception:
                        continue
            
            return models
        except Exception:
            return []
    
    def test_interactions(self):
        """测试页面交互"""
        if not self.detected_models:
            print("  ⚠️  没有检测到车型，跳过交互测试")
            return
        
        print(f"  🎯 测试与第一个车型的交互: {self.detected_models[0]['name']}")
        
        try:
            model_element = self.driver.find_element(By.CSS_SELECTOR, f'div[data-cy="{self.detected_models[0]["name"]}"]')
            
            # 记录点击前状态
            before_url = self.driver.current_url
            
            # 尝试点击
            self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", model_element)
            time.sleep(1)
            model_element.click()
            
            # 等待响应
            time.sleep(3)
            
            # 检查变化
            after_url = self.driver.current_url
            
            if before_url != after_url:
                print(f"  ✅ 交互成功! URL发生变化")
                print(f"     变化: {before_url} → {after_url}")
            else:
                print(f"  ⚠️  点击完成但URL未变化")
            
        except Exception as e:
            print(f"  ❌ 交互测试失败: {e}")
    
    def generate_stable_report(self):
        """生成稳定版报告"""
        report = {
            'analysis_timestamp': time.time(),
            'browser_stable': self.check_browser_health(),
            'analysis_results': self.analysis_results,
            'summary': {
                'models_detected': len(self.detected_models),
                'navigation_items': len(self.analysis_results.get('navigation', [])),
                'page_html_size': self.analysis_results.get('page_info', {}).get('html_length', 0)
            }
        }
        
        # 保存报告
        with open("stable_analysis_report.json", "w", encoding="utf-8") as f:
            json.dump(report, f, indent=2, ensure_ascii=False)
        
        print("  ✅ 报告已保存: stable_analysis_report.json")
        
        # 显示摘要
        print("\\n📊 分析摘要:")
        print(f"    • 浏览器状态: {'正常' if report['browser_stable'] else '异常'}")
        print(f"    • 检测车型: {report['summary']['models_detected']} 个")
        print(f"    • 导航项目: {report['summary']['navigation_items']} 个")
        print(f"    • 页面大小: {report['summary']['page_html_size']:,} 字符")
        
        # 显示车型列表
        if self.detected_models:
            print("\\n🚗 检测到的车型:")
            for i, model in enumerate(self.detected_models, 1):
                print(f"    {i}. {model['name']}")
    
    def cleanup(self):
        """清理资源"""
        if self.driver:
            try:
                self.driver.quit()
                print("🔚 浏览器已关闭")
            except Exception as e:
                print(f"❌ 关闭浏览器出错: {e}")


def main():
    """主函数"""
    url = "https://www.ford.co.uk/shop/build-your-ford/ngc2/ice2/model?catalogId=WAEGB-CGE-2022-FocusMCAGBR202450&series=ACMAA_VS-D3&paint=PN4A7&planId=c"
    
    print("福特配置器稳定版分析器")
    print("=" * 60)
    print("🔧 优化特性:")
    print("   • 渐进式加载检查（15秒总时长）")
    print("   • 浏览器健康状态监控")
    print("   • 增强的错误处理和恢复")
    print("   • 保守的Cookie处理策略")
    print("   • 实时交互验证")
    print("=" * 60)
    
    analyzer = StableConfiguratorAnalyzer()
    analyzer.analyze_with_progressive_loading(url)


if __name__ == "__main__":
    main()